/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package src.services.loan;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.hibernate.HibernateException;
import org.hibernate.Query;
import org.hibernate.Session;
import src.HibernateUtil;
import src.domain.loan.Loan;
import src.domain.loan.LoanInstallment;
import src.services.CRUEDService;
import src.util.Constanta;
import src.util.Utils;

/**
 *
 * @author jasuke
 */
public class LoanInstallmentModel {

    public LoanInstallmentModel() {
    }
    
    public LoanInstallment nextPayment(Integer id) {
               
        Session session = HibernateUtil.getSessionFactory().getCurrentSession();
        org.hibernate.Transaction tx = session.beginTransaction();
        LoanInstallment installment = new LoanInstallment();   
        
        try {
            String hql = "from LoanInstallment loan where loan.id.loanId = "+id+" and paid = 0 order by loan.id.seq";
            Query q = session.createQuery(hql).setMaxResults(1);
            installment = (LoanInstallment) q.uniqueResult();
            tx.commit();
            
        } catch (RuntimeException e) {
            if (tx != null && tx.isActive()) {
                try {tx.rollback(); } 
                catch (HibernateException e1) {}
            }
            Logger.getLogger(LoanInstallmentModel.class.getName()).log(Level.SEVERE, null, e);
        }
        finally {}
        
        return installment;
    }
    
    public List<LoanInstallment> calculate(Loan loan) {
                
        List<LoanInstallment> installs = new ArrayList<>();
       
        BigDecimal saldoAwal = loan.getPrincipalAmount();
        BigDecimal loanIntRate = loan.getInterestRate().divide(BigDecimal.valueOf(100), 4, RoundingMode.HALF_DOWN);
        int interval = loan.getPeriod();
        BigDecimal n = new BigDecimal(interval).divide(BigDecimal.valueOf(12), 4, RoundingMode.HALF_DOWN);
        
        BigDecimal principalAmount = loan.getPrincipalAmount().divide(BigDecimal.valueOf(interval), 0, RoundingMode.HALF_DOWN);
        BigDecimal outstanding = loan.getPrincipalAmount();   
        BigDecimal outstandingInterest = BigDecimal.ZERO; 
        
        //hitung outstandingBunga
         switch (loan.getInterestType()) {
             case Constanta.INTTYPE_FLAT: 
                    outstandingInterest = loan.getPrincipalAmount().multiply(loanIntRate).multiply(n);
             break;
             case Constanta.INTTYPE_EFFECTIVE: 
                    
             break;
                 
         }
        for (int i=1; i<= interval; i++) {
        
            BigDecimal intTotal;// = BigDecimal.ZERO;
            BigDecimal interestAmount = BigDecimal.ZERO;
            BigDecimal amount = BigDecimal.ZERO;
            
            Date date = Utils.setMoth(loan.getDisbursementDate(), i);
            
            switch (loan.getInterestType()) {
                case Constanta.INTTYPE_FLAT:
                    intTotal = loan.getPrincipalAmount().multiply(loanIntRate).multiply(n);
                   
                    interestAmount = intTotal.divide(BigDecimal.valueOf(interval), 0, RoundingMode.HALF_DOWN);
                    amount = loan.getPrincipalAmount().add(intTotal).divide(BigDecimal.valueOf(interval), 0, RoundingMode.HALF_DOWN);
                    if (i==interval){
                        principalAmount = outstanding;
                        interestAmount = outstandingInterest;
                        amount = principalAmount.add(interestAmount);                        
                        outstanding = BigDecimal.ZERO;
                        outstandingInterest = BigDecimal.ZERO;
                    }
                    
                    else {
                        outstanding =  outstanding.subtract(principalAmount);
                        outstandingInterest = outstandingInterest.subtract(interestAmount);
                    }
                   
                    break;

                case Constanta.INTTYPE_EFFECTIVE: 
                    BigDecimal x = saldoAwal.multiply(loanIntRate);
                    interestAmount = x.divide(BigDecimal.valueOf(12), 0, RoundingMode.HALF_DOWN);
                    
                    saldoAwal = saldoAwal.subtract(principalAmount);
                    
                    if (i==interval){
                        principalAmount = outstanding; outstanding = BigDecimal.ZERO;
                    }                        
                    else outstanding = outstanding.subtract(principalAmount); 
                    
                    amount = principalAmount.add(interestAmount);
                    break;
            }
            /*
            Loansimulate loansimulate = new Loansimulate();
            loansimulate.setPaymentIdx(i);
            loansimulate.setAmount(principalAmount);
            loansimulate.setInterest(interestAmount);
            loansimulate.setTotal(amount);
            loansimulate.setDate(date);
            loansimulate.setOutstanding(outstanding);
            loansimulate.setOutstandingInterest(outstandingInterest);
            loansimulate.setDescription("Angsuran ke "+i);
            
             * 
            */
            //saldoAwal = saldoAwal.subtract(tagihanPokok);
            LoanInstallment install = new LoanInstallment();
            install.setDueDate(date);
            install.setInterestAmount(interestAmount);
            install.setPrincipleAmount(principalAmount);
            install.setOwingAmount(outstanding);
            install.setPaid(false);
            //install.setId(new LoanInstallmentId(loan.getLoanId(), i));
            installs.add(install);
           
        }
         
        return installs;
    }
    
}
